{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6umP1IKf4Dg6"
   },
   "source": [
    "# Autobatching for Bayesian Inference\n",
    "\n",
    "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/google/jax/blob/main/docs/notebooks/vmapped_log_probs.ipynb) [![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/google/jax/blob/main/docs/notebooks/vmapped_log_probs.ipynb)\n",
    "\n",
    "This notebook demonstrates a simple Bayesian inference example where autobatching makes user code easier to write, easier to read, and less likely to include bugs.\n",
    "\n",
    "Inspired by a notebook by @davmre."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "id": "8RZDkfbV3zdR"
   },
   "outputs": [],
   "source": [
    "import functools\n",
    "import itertools\n",
    "import re\n",
    "import sys\n",
    "import time\n",
    "\n",
    "from matplotlib.pyplot import *\n",
    "\n",
    "import jax\n",
    "\n",
    "from jax import lax\n",
    "import jax.numpy as jnp\n",
    "import jax.scipy as jsp\n",
    "from jax import random\n",
    "\n",
    "import numpy as np\n",
    "import scipy as sp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "p2VcZS1d34C6"
   },
   "source": [
    "## Generate a fake binary classification dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "id": "pq41hMvn4c_i"
   },
   "outputs": [],
   "source": [
    "np.random.seed(10009)\n",
    "\n",
    "num_features = 10\n",
    "num_points = 100\n",
    "\n",
    "true_beta = np.random.randn(num_features).astype(jnp.float32)\n",
    "all_x = np.random.randn(num_points, num_features).astype(jnp.float32)\n",
    "y = (np.random.rand(num_points) < sp.special.expit(all_x.dot(true_beta))).astype(jnp.int32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "id": "O0nVumAw7IlT",
    "outputId": "751a3290-a81b-4538-9183-16cd685fbaf9"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0,\n",
       "       1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,\n",
       "       1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,\n",
       "       0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,\n",
       "       1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0], dtype=int32)"
      ]
     },
     "execution_count": 11,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DZRVvhpn5aB1"
   },
   "source": [
    "## Write the log-joint function for the model\n",
    "\n",
    "We'll write a non-batched version, a manually batched version, and an autobatched version."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "C_mDXInL7nsP"
   },
   "source": [
    "### Non-batched"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "id": "ZHyL2sJh5ajG"
   },
   "outputs": [],
   "source": [
    "def log_joint(beta):\n",
    "    result = 0.\n",
    "    # Note that no `axis` parameter is provided to `jnp.sum`.\n",
    "    result = result + jnp.sum(jsp.stats.norm.logpdf(beta, loc=0., scale=1.))\n",
    "    result = result + jnp.sum(-jnp.log(1 + jnp.exp(-(2*y-1) * jnp.dot(all_x, beta))))\n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "id": "e51qW0ro6J7C",
    "outputId": "2ec6bbbd-12ee-45bc-af76-5111c53e4d5a"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array(-213.23558, dtype=float32)"
      ]
     },
     "execution_count": 13,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "log_joint(np.random.randn(num_features))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "id": "fglQXK1Y6wnm",
    "outputId": "2b934336-08ad-4776-9a58-aa575bf601eb"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Caught expected exception Incompatible shapes for broadcasting: ((100, 10), (1, 100))\n"
     ]
    }
   ],
   "source": [
    "# This doesn't work, because we didn't write `log_prob()` to handle batching.\n",
    "try:\n",
    "  batch_size = 10\n",
    "  batched_test_beta = np.random.randn(batch_size, num_features)\n",
    "\n",
    "  log_joint(np.random.randn(batch_size, num_features))\n",
    "except ValueError as e:\n",
    "  print(\"Caught expected exception \" + str(e))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_lQ8MnKq7sLU"
   },
   "source": [
    "### Manually batched"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "id": "2g5-4bQE7gRA"
   },
   "outputs": [],
   "source": [
    "def batched_log_joint(beta):\n",
    "    result = 0.\n",
    "    # Here (and below) `sum` needs an `axis` parameter. At best, forgetting to set axis\n",
    "    # or setting it incorrectly yields an error; at worst, it silently changes the\n",
    "    # semantics of the model.\n",
    "    result = result + jnp.sum(jsp.stats.norm.logpdf(beta, loc=0., scale=1.),\n",
    "                           axis=-1)\n",
    "    # Note the multiple transposes. Getting this right is not rocket science,\n",
    "    # but it's also not totally mindless. (I didn't get it right on the first\n",
    "    # try.)\n",
    "    result = result + jnp.sum(-jnp.log(1 + jnp.exp(-(2*y-1) * jnp.dot(all_x, beta.T).T)),\n",
    "                           axis=-1)\n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "KdDMr-Gy85CO",
    "outputId": "db746654-68e9-43b8-ce3b-6e5682e22eb5"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([-147.84033203, -207.02204895, -109.26074982, -243.80830383,\n",
       "       -163.02911377, -143.84848022, -160.28771973, -113.77169037,\n",
       "       -126.60544586, -190.81988525], dtype=float32)"
      ]
     },
     "execution_count": 16,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "batch_size = 10\n",
    "batched_test_beta = np.random.randn(batch_size, num_features)\n",
    "\n",
    "batched_log_joint(batched_test_beta)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "-uuGlHQ_85kd"
   },
   "source": [
    "### Autobatched with vmap\n",
    "\n",
    "It just works."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "id": "SU20bouH8-Za",
    "outputId": "ee450298-982f-4b9a-bed9-a6f9b8f63d92"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Array([-147.84033203, -207.02204895, -109.26074982, -243.80830383,\n",
       "       -163.02911377, -143.84848022, -160.28771973, -113.77169037,\n",
       "       -126.60544586, -190.81988525], dtype=float32)"
      ]
     },
     "execution_count": 17,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vmap_batched_log_joint = jax.vmap(log_joint)\n",
    "vmap_batched_log_joint(batched_test_beta)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "L1KNBo9y_yZJ"
   },
   "source": [
    "## Self-contained variational inference example\n",
    "\n",
    "A little code is copied from above."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lQTPaaQMJh8Y"
   },
   "source": [
    "### Set up the (batched) log-joint function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "id": "AITXbaofA3Pm"
   },
   "outputs": [],
   "source": [
    "@jax.jit\n",
    "def log_joint(beta):\n",
    "    result = 0.\n",
    "    # Note that no `axis` parameter is provided to `jnp.sum`.\n",
    "    result = result + jnp.sum(jsp.stats.norm.logpdf(beta, loc=0., scale=10.))\n",
    "    result = result + jnp.sum(-jnp.log(1 + jnp.exp(-(2*y-1) * jnp.dot(all_x, beta))))\n",
    "    return result\n",
    "\n",
    "batched_log_joint = jax.jit(jax.vmap(log_joint))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "UmmFMQ8LJk6a"
   },
   "source": [
    "### Define the ELBO and its gradient"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "id": "MJtnskL6BKwV"
   },
   "outputs": [],
   "source": [
    "def elbo(beta_loc, beta_log_scale, epsilon):\n",
    "    beta_sample = beta_loc + jnp.exp(beta_log_scale) * epsilon\n",
    "    return jnp.mean(batched_log_joint(beta_sample), 0) + jnp.sum(beta_log_scale - 0.5 * np.log(2*np.pi))\n",
    " \n",
    "elbo = jax.jit(elbo)\n",
    "elbo_val_and_grad = jax.jit(jax.value_and_grad(elbo, argnums=(0, 1)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "oQC7xKYnJrp5"
   },
   "source": [
    "### Optimize the ELBO using SGD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "id": "9JrD5nNgH715",
    "outputId": "80bf62d8-821a-45c4-885c-528b2e449e97"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\t-180.85391235351562\n",
      "10\t-113.06047058105469\n",
      "20\t-102.73725891113281\n",
      "30\t-99.78732299804688\n",
      "40\t-98.90898895263672\n",
      "50\t-98.29743957519531\n",
      "60\t-98.18630981445312\n",
      "70\t-97.5797348022461\n",
      "80\t-97.28599548339844\n",
      "90\t-97.46998596191406\n",
      "100\t-97.47715759277344\n",
      "110\t-97.5806884765625\n",
      "120\t-97.49433898925781\n",
      "130\t-97.50270080566406\n",
      "140\t-96.86398315429688\n",
      "150\t-97.44197082519531\n",
      "160\t-97.06938934326172\n",
      "170\t-96.84031677246094\n",
      "180\t-97.21339416503906\n",
      "190\t-97.56500244140625\n",
      "200\t-97.26395416259766\n",
      "210\t-97.11984252929688\n",
      "220\t-97.39595794677734\n",
      "230\t-97.16830444335938\n",
      "240\t-97.11840057373047\n",
      "250\t-97.24346160888672\n",
      "260\t-97.29786682128906\n",
      "270\t-96.69286346435547\n",
      "280\t-96.96443176269531\n",
      "290\t-97.3005599975586\n",
      "300\t-96.63589477539062\n",
      "310\t-97.0351791381836\n",
      "320\t-97.52906799316406\n",
      "330\t-97.2880630493164\n",
      "340\t-97.07324981689453\n",
      "350\t-97.15620422363281\n",
      "360\t-97.25880432128906\n",
      "370\t-97.19515228271484\n",
      "380\t-97.13092803955078\n",
      "390\t-97.11730194091797\n",
      "400\t-96.93872833251953\n",
      "410\t-97.26676940917969\n",
      "420\t-97.35321044921875\n",
      "430\t-97.2100830078125\n",
      "440\t-97.28434753417969\n",
      "450\t-97.16310119628906\n",
      "460\t-97.26123809814453\n",
      "470\t-97.21342468261719\n",
      "480\t-97.23995971679688\n",
      "490\t-97.1491470336914\n",
      "500\t-97.23527526855469\n",
      "510\t-96.93415832519531\n",
      "520\t-97.21208190917969\n",
      "530\t-96.82577514648438\n",
      "540\t-97.01283264160156\n",
      "550\t-96.9417724609375\n",
      "560\t-97.16526794433594\n",
      "570\t-97.29165649414062\n",
      "580\t-97.42940521240234\n",
      "590\t-97.24371337890625\n",
      "600\t-97.15219116210938\n",
      "610\t-97.4984359741211\n",
      "620\t-96.99072265625\n",
      "630\t-96.88955688476562\n",
      "640\t-96.89968872070312\n",
      "650\t-97.13794708251953\n",
      "660\t-97.43705749511719\n",
      "670\t-96.99232482910156\n",
      "680\t-97.15624237060547\n",
      "690\t-97.1869125366211\n",
      "700\t-97.1115951538086\n",
      "710\t-97.78104400634766\n",
      "720\t-97.23224639892578\n",
      "730\t-97.16204071044922\n",
      "740\t-96.99580383300781\n",
      "750\t-96.66720581054688\n",
      "760\t-97.16795349121094\n",
      "770\t-97.51432037353516\n",
      "780\t-97.28899383544922\n",
      "790\t-96.91226959228516\n",
      "800\t-97.17100524902344\n",
      "810\t-97.29046630859375\n",
      "820\t-97.16242980957031\n",
      "830\t-97.19109344482422\n",
      "840\t-97.5638427734375\n",
      "850\t-97.00192260742188\n",
      "860\t-96.86555480957031\n",
      "870\t-96.76338195800781\n",
      "880\t-96.83660125732422\n",
      "890\t-97.121826171875\n",
      "900\t-97.09553527832031\n",
      "910\t-97.06825256347656\n",
      "920\t-97.1194839477539\n",
      "930\t-96.87931823730469\n",
      "940\t-97.45622253417969\n",
      "950\t-96.69277954101562\n",
      "960\t-97.29376983642578\n",
      "970\t-97.33528137207031\n",
      "980\t-97.349609375\n",
      "990\t-97.09675598144531\n"
     ]
    }
   ],
   "source": [
    "def normal_sample(key, shape):\n",
    "    \"\"\"Convenience function for quasi-stateful RNG.\"\"\"\n",
    "    new_key, sub_key = random.split(key)\n",
    "    return new_key, random.normal(sub_key, shape)\n",
    "\n",
    "normal_sample = jax.jit(normal_sample, static_argnums=(1,))\n",
    "\n",
    "key = random.key(10003)\n",
    "\n",
    "beta_loc = jnp.zeros(num_features, jnp.float32)\n",
    "beta_log_scale = jnp.zeros(num_features, jnp.float32)\n",
    "\n",
    "step_size = 0.01\n",
    "batch_size = 128\n",
    "epsilon_shape = (batch_size, num_features)\n",
    "for i in range(1000):\n",
    "    key, epsilon = normal_sample(key, epsilon_shape)\n",
    "    elbo_val, (beta_loc_grad, beta_log_scale_grad) = elbo_val_and_grad(\n",
    "        beta_loc, beta_log_scale, epsilon)\n",
    "    beta_loc += step_size * beta_loc_grad\n",
    "    beta_log_scale += step_size * beta_log_scale_grad\n",
    "    if i % 10 == 0:\n",
    "        print('{}\\t{}'.format(i, elbo_val))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "b3ZAe5fJJ2KM"
   },
   "source": [
    "### Display the results\n",
    "\n",
    "Coverage isn't quite as good as we might like, but it's not bad, and nobody said variational inference was exact."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "id": "zt1NBLoVHtOG",
    "outputId": "fb159795-e6e7-497c-e501-9933ec761af4"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f90aed84860>"
      ]
     },
     "execution_count": 24,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 504x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "figure(figsize=(7, 7))\n",
    "plot(true_beta, beta_loc, '.', label='Approximated Posterior Means')\n",
    "plot(true_beta, beta_loc + 2*jnp.exp(beta_log_scale), 'r.', label='Approximated Posterior $2\\sigma$ Error Bars')\n",
    "plot(true_beta, beta_loc - 2*jnp.exp(beta_log_scale), 'r.')\n",
    "plot_scale = 3\n",
    "plot([-plot_scale, plot_scale], [-plot_scale, plot_scale], 'k')\n",
    "xlabel('True beta')\n",
    "ylabel('Estimated beta')\n",
    "legend(loc='best')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "id": "_bXdOlvUEJl0"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "vmapped_log_probs.ipynb",
   "provenance": []
  },
  "jupytext": {
   "formats": "ipynb,md:myst"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
